package lib.quasar.widget.chart.draw;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.text.TextUtils;

import java.text.DecimalFormat;

import lib.quasar.util.DimenUtil;
import lib.quasar.widget.R;
import lib.quasar.widget.chart.ChartView;
import lib.quasar.widget.chart.entry.Entry;
import lib.quasar.widget.chart.paint.StockPaint;

/**
 * description: 化验单
 * created by kalu on 2018/3/29 16:59
 */
public final class DrawAssay implements IDraw {

    private float left, right, top, bottom;
    private float marginLeft, marginRight, marginTop, marginBottom;
    private float width, height, centerX, centerY;
    private float paddingLeft, paddingTop, paddingRight, paddingBottom;

    private final Rect mTextRect = new Rect();
    private final float[] mDashLine = new float[4];

    @Override
    public void onDrawInit(float left, float top, float right, float bottom,
                           float marginLeft, float marginTop, float marginRight, float marginBottom,
                           float paddingLeft, float paddingTop, float paddingRight, float paddingBottom,
                           float width, float height, float centerX, float centerY, int model) {

        if (model != ChartView.DRAW_ASSAY) return;

        this.left = left;
        this.right = right;
        this.top = top;
        this.bottom = bottom;

        this.marginLeft = marginLeft;
        this.marginTop = marginTop;
        this.marginRight = marginRight;
        this.marginBottom = marginBottom;

        this.paddingLeft = paddingLeft;
        this.paddingTop = paddingTop;
        this.paddingRight = paddingRight;
        this.paddingBottom = paddingBottom;

        this.width = width;
        this.height = height;
        this.centerX = centerX;
        this.centerY = centerY;
    }

    @Override
    public void onDrawNull(Context context, ChartView chart, Canvas canvas, String hint, int model) {

        if (model != ChartView.DRAW_ASSAY) return;

        canvas.save();
        drawBackground(context, chart, canvas, hint);
        canvas.restore();
    }

    @Override
    public void onDrawData(Context context, ChartView chart, Canvas canvas, float xHighligh, float yHighligh, int model) {

        if (model != ChartView.DRAW_ASSAY) return;

        canvas.save();
        drawLine(context, chart, canvas, xHighligh, yHighligh);
        drawBackground(context, chart, canvas, "");
        canvas.restore();
    }

    private final void drawLine(Context context, ChartView chart, Canvas canvas, float xHighligh, float yHighligh) {

        if (chart.isEmpty()) return;

        final float chartLeft = left + marginLeft + paddingLeft;
        final float chartTop = top + marginTop + paddingTop;
        final float chartRight = right - marginRight - paddingRight;
        final float chartBottom = bottom - marginBottom - paddingBottom;
        final float chartHeight = chartBottom - chartTop;
        final float chartWidth = chartRight - chartLeft;

        final int dotCountDefault = chart.getDotCountDefault();
        final float segment = chartWidth / (dotCountDefault - 1);

        float beforeX = -1f, beforeY = -1f;
        final int begin = chart.getDotBegin();
        final int end = chart.getDotEnd() - 1;

        for (int i = begin; i <= end; i++) {

            final Entry entry = chart.getEntryList().get(i);

            final int position = (i - begin);
            final float tempX = chartLeft + segment * position;

            float value = entry.getValue();
            final float axisYMax = entry.getAxisYMax();
            final float axisYMin = entry.getAxisYMin();
            if (value > axisYMax) {
                value = axisYMax;
            } else if (value < axisYMin) {
                value = axisYMin;
            }

            final float temp1 = axisYMax - value;
            final float temp2 = axisYMax - axisYMin;
            final float tempY = temp1 * chartHeight / temp2 + chartTop;

            if (i == begin) {
                // 点
                final boolean isRed = (entry.getValue() < 35.7f || entry.getValue() > 37.3f);
                final Paint dotPaint = StockPaint.getDotPaint(isRed ? StockPaint.RED : StockPaint.GREEN);
                canvas.drawCircle(tempX, tempY, StockPaint.DOT_RADIUS, dotPaint);
                // 字
                final Paint axisPaint = StockPaint.getAxisTextPaint(Paint.Align.LEFT, StockPaint.BLACK);
                final String temperature = String.valueOf(entry.getValue());
                axisPaint.getTextBounds(temperature, 0, temperature.length(), mTextRect);
                canvas.drawText(temperature, tempX + mTextRect.width() * 0.2f, tempY, axisPaint);
                beforeX = tempX;
                beforeY = tempY;
            } else if (i == end) {
                // 线
                final Paint linePaint = StockPaint.getLinePaint(StockPaint.GREEN);
                canvas.drawLine(beforeX, beforeY, tempX, tempY, linePaint);
                // 点
                final boolean isRed = (entry.getValue() < 35.7f || entry.getValue() > 37.3f);
                final Paint dotPaint = StockPaint.getDotPaint(isRed ? StockPaint.RED : StockPaint.GREEN);
                canvas.drawCircle(tempX, tempY, StockPaint.DOT_RADIUS, dotPaint);
                // 字
                final Paint axisPaint = StockPaint.getAxisTextPaint(Paint.Align.RIGHT, StockPaint.BLACK);
                final String temperature = String.valueOf(entry.getValue());
                axisPaint.getTextBounds(temperature, 0, temperature.length(), mTextRect);
                canvas.drawText(temperature, tempX - mTextRect.width() * 0.2f, tempY, axisPaint);
            } else {
                // 线
                final Paint linePaint = StockPaint.getLinePaint(StockPaint.GREEN);
                canvas.drawLine(beforeX, beforeY, tempX, tempY, linePaint);
                // 点
                final boolean isRed = (entry.getValue() < 35.7f || entry.getValue() > 37.3f);
                final Paint dotPaint = StockPaint.getDotPaint(isRed ? StockPaint.RED : StockPaint.GREEN);
                canvas.drawCircle(tempX, tempY, StockPaint.DOT_RADIUS, dotPaint);
                // 点
                final Entry entryBefore = chart.getEntryList().get(i - 1);
                final boolean isRedBefore = (entryBefore.getValue() < 35.7f || entryBefore.getValue() > 37.3f);
                final Paint dotPaintBefore = StockPaint.getDotPaint(isRedBefore ? StockPaint.RED : StockPaint.GREEN);
                canvas.drawCircle(beforeX, beforeY, StockPaint.DOT_RADIUS, dotPaintBefore);
                // 字
                if (tempY >= beforeY) {
                    final Paint axisPaint = StockPaint.getAxisTextPaint(Paint.Align.LEFT, StockPaint.BLACK);
                    final String temperature = String.valueOf(entry.getValue());
                    axisPaint.getTextBounds(temperature, 0, temperature.length(), mTextRect);
                    canvas.drawText(temperature, tempX + mTextRect.width() * 0.2f, tempY + mTextRect.height(), axisPaint);
                } else {
                    final Paint axisPaint = StockPaint.getAxisTextPaint(Paint.Align.LEFT, StockPaint.BLACK);
                    final String temperature = String.valueOf(entry.getValue());
                    axisPaint.getTextBounds(temperature, 0, temperature.length(), mTextRect);
                    canvas.drawText(temperature, tempX + mTextRect.width() * 0.2f, tempY - mTextRect.height() * 0.5f, axisPaint);
                }
                beforeX = tempX;
                beforeY = tempY;
            }
        }
    }

    private final void drawBackground(Context context, ChartView chart, Canvas canvas, String hint) {

        final float chartLeft = left + marginLeft;
        final float chartTop = top + marginTop;
        final float chartRight = right - marginRight;
        final float chartBottom = bottom - marginBottom;
        final float chartHeight = chartBottom - chartTop;
        final float chartWidth = chartRight - chartLeft;

        // x轴
        canvas.drawLine(chartLeft, chartTop, chartLeft, chartBottom, StockPaint.getAxisPaint(StockPaint.BLACK));
        final float segmentX = (chartWidth - paddingLeft - paddingRight) / (chart.getDotCountDefault() - 1);
        final int begin = chart.getDotBegin();
        final int end = Math.max(chart.getDotEnd(), chart.getDotCountDefault()) - 1;
        for (int i = begin; i <= end; i++) {

            final int position = (i - chart.getDotBegin());
            final float textX = chartLeft + paddingLeft + segmentX * position;
            if (i > begin) {
                canvas.drawLine(textX, chartBottom - DimenUtil.dp2px(4), textX, chartBottom, StockPaint.getLinePaint(StockPaint.BLACK));
            }

            if (chart.isEmpty() || position >= chart.getDotCountReal() || i < 0) continue;

            final Entry entry = chart.getEntryList().get(i);
            final String date = entry.getAxisX();
            if (i == begin) {
                final Paint axisPaint = StockPaint.getAxisTextPaint(Paint.Align.LEFT, StockPaint.BLACK);
                axisPaint.getTextBounds(date, 0, date.length(), mTextRect);
                canvas.drawText(date, textX, chartBottom + mTextRect.height() * 1.5f, axisPaint);
            } else if (i == end) {
                final Paint axisPaint = StockPaint.getAxisTextPaint(Paint.Align.RIGHT, StockPaint.BLACK);
                axisPaint.getTextBounds(date, 0, date.length(), mTextRect);
                canvas.drawText(date, textX, chartBottom + mTextRect.height() * 1.5f, axisPaint);
            } else {
                final Paint axisPaint = StockPaint.getAxisTextPaint(Paint.Align.CENTER, StockPaint.BLACK);
                axisPaint.getTextBounds(date, 0, date.length(), mTextRect);
                canvas.drawText(date, textX, chartBottom + mTextRect.height() * 1.5f, axisPaint);
            }
        }

        // y轴
        canvas.drawLine(chartLeft, chartBottom, chartRight, chartBottom, StockPaint.getAxisPaint(StockPaint.BLACK));
        // 单位
//        final String unit = "°C";
//        final Paint unitPaint = StockPaint.getAxisTextPaint(Paint.Align.LEFT, StockPaint.BLACK, DimenUtil.sp2px(12.4f));
//        unitPaint.getTextBounds(unit, 0, unit.length(), mTextRect);
//        canvas.drawText(unit, chartLeft - mTextRect.width() * 0.5f, chartTop - mTextRect.height(), unitPaint);

        final float textX = chartLeft * 0.9f;

        for (int i = 0; i <= chart.getSegmentY(); i++) {

            final float textY = chartTop + i * (chartHeight / chart.getSegmentY());
            if (i < chart.getSegmentY()) {
                canvas.drawLine(chartLeft, textY, chartLeft + DimenUtil.dp2px(4), textY, StockPaint.getLinePaint(StockPaint.BLACK));
            }
            if (chart.isEmpty()) continue;

            final float maxValue = chart.getEntryList().get(0).getAxisYMax();
            final float minValue = chart.getEntryList().get(0).getAxisYMin();

            final float average = (maxValue - minValue) / chart.getSegmentY();
            if (i == 0) {
                final String str = String.valueOf((int)maxValue);
                final Paint axisPaint = StockPaint.getAxisTextPaint(Paint.Align.RIGHT, StockPaint.BLACK);
                axisPaint.getTextBounds(str, 0, str.length(), mTextRect);
                canvas.drawText(str, textX, chartTop + mTextRect.height(), axisPaint);
            } else if (i == chart.getSegmentY()) {
                final String str = String.valueOf((int)minValue);
                final Paint axisPaint = StockPaint.getAxisTextPaint(Paint.Align.RIGHT, StockPaint.BLACK);
                canvas.drawText(str, textX, chartBottom, axisPaint);
            } else {
                final String str = String.valueOf((int) (maxValue - average * i));
                final Paint axisPaint = StockPaint.getAxisTextPaint(Paint.Align.RIGHT, StockPaint.BLACK);
                axisPaint.getTextBounds(str, 0, str.length(), mTextRect);
                canvas.drawText(str, textX, textY + mTextRect.height() * 0.5f, axisPaint);
            }
        }

        // 安全值
        if (!chart.isEmpty()) {

            final float maxValue = chart.getEntryList().get(0).getAxisYMax();
            final float minValue = chart.getEntryList().get(0).getAxisYMin();

            // Max
            final float warningMax1 = maxValue - 37.3f;
            final float warningMax2 = maxValue - minValue;
            final float warningMaxY = warningMax1 * chartHeight / warningMax2 + chartTop;
            final float warningMaxBegin1 = chartLeft + 2;
            final float warningMaxBegin2 = warningMaxBegin1 + 5;
            mDashLine[0] = warningMaxBegin1;
            mDashLine[2] = warningMaxBegin2;
            mDashLine[1] = mDashLine[3] = warningMaxY;
            while (mDashLine[0] <= chartRight) {
                canvas.drawLines(mDashLine, StockPaint.getDashPaint(StockPaint.BLACK));
                final float x1Temp = mDashLine[0];
                final float x2Temp = mDashLine[2];
                mDashLine[0] = x1Temp + 15;
                mDashLine[2] = Math.min(x2Temp + 15, right);
            }
//            final String warningMaxText = String.valueOf(37.3);
//            final Paint warningMaxTextPaint = StockPaint.getAxisTextPaint(Paint.Align.RIGHT, StockPaint.BLACK);
//            warningMaxTextPaint.getTextBounds(warningMaxText, 0, warningMaxText.length(), mTextRect);
//            canvas.drawText(warningMaxText, textX, warningMaxY + mTextRect.height() * 0.5f, warningMaxTextPaint);

            // Min
            final float warningMin1 = maxValue - 35.7f;
            final float warningMin2 = maxValue - minValue;
            final float warningMinY = warningMin1 * chartHeight / warningMin2 + chartTop;
            final float warningMinBegin1 = chartLeft + 2;
            final float warningMinBegin2 = warningMinBegin1 + 5;
            mDashLine[0] = warningMinBegin1;
            mDashLine[2] = warningMinBegin2;
            mDashLine[1] = mDashLine[3] = warningMinY;
            while (mDashLine[0] <= chartRight) {
                canvas.drawLines(mDashLine, StockPaint.getDashPaint(StockPaint.BLACK));
                final float x1Temp = mDashLine[0];
                final float x2Temp = mDashLine[2];
                mDashLine[0] = x1Temp + 15;
                mDashLine[2] = Math.min(x2Temp + 15, right);
            }
//            final String warningMinText = String.valueOf(35.7);
//            final Paint warningMinTextPaint = StockPaint.getAxisTextPaint(Paint.Align.RIGHT, StockPaint.BLACK);
//            warningMinTextPaint.getTextBounds(warningMinText, 0, warningMinText.length(), mTextRect);
//            canvas.drawText(warningMinText, textX, warningMinY + mTextRect.height() * 0.5f, warningMinTextPaint);
        }

        if (TextUtils.isEmpty(hint)) return;
        final Paint hintPaint = StockPaint.getAxisTextPaint(Paint.Align.CENTER, StockPaint.BLACK, DimenUtil.sp2px(12.4f));
        canvas.drawText(hint, centerX, centerY, hintPaint);
    }
}